package com.bolingcavalry.crm.taskorder.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.MessageTypeEnum;
import com.base.ResponseResult;
import com.base.RoleEnum;
import com.base.Status;
import com.bolingcavalry.crm.aftersales.mapper.AfterSalesMapper;
import com.bolingcavalry.crm.aftersales.service.AfterSalesService;
import com.bolingcavalry.crm.message.config.RabbitMQConstants;
import com.bolingcavalry.crm.message.mapper.MessageMapper;
import com.bolingcavalry.crm.minio.service.MinioService;
import com.bolingcavalry.crm.product.mapper.ProductMapper;
import com.bolingcavalry.crm.productinstallinfo.mapper.ProductInstallInfoMapper;
import com.bolingcavalry.crm.receiver.mapper.ReceiverMapper;
import com.bolingcavalry.crm.recyclebin.mapper.RecyclebinMapper;
import com.bolingcavalry.crm.recyclebin.service.OrderRestoreService;
import com.bolingcavalry.crm.security.utils.SecurityUtils;
import com.bolingcavalry.crm.serviceorder.mapper.ServiceOrderMapper;
import com.bolingcavalry.crm.taskorder.mapper.DeviceInstallInfoMapper;
import com.bolingcavalry.crm.taskorder.mapper.TaskorderMapper;
import com.bolingcavalry.crm.taskorder.service.ConfirmationService;
import com.bolingcavalry.crm.taskorder.service.TaskorderService;
import com.bolingcavalry.crm.utils.AUtils;
import com.dto.ProductInstallInfoDTO;
import com.dto.TaskOrderDTO;
import com.dto.TaskReviewMessageDTO;
import com.entity.aftersales.AfterSales;
import com.entity.message.Message;
import com.entity.receiver.Receiver;
import com.entity.recyclebin.RecycleBinOrder;
import com.entity.product.Product;
import com.entity.serviceorder.ServiceOrder;
import com.entity.taskorder.ProductInstallInfo;
import com.entity.taskorder.TaskOrder;
import com.vo.ConfirmationOrderVO;
import com.vo.ProductInstallInfoVO;
import com.vo.TaskOrderVO;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;

import static com.bolingcavalry.crm.utils.AUtils.HTTP_CLIENT;
import static com.bolingcavalry.crm.utils.AUtils.getAccessToken;

@Service(Status.TASK_ORDER)
@Slf4j
public class TaskorderServiceImpl implements TaskorderService, OrderRestoreService {
    @Autowired
    private TaskorderMapper taskorderMapper;
    @Autowired
    private AUtils aUtils;
    @Autowired
    private DeviceInstallInfoMapper deviceInstallInfoMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private RecyclebinMapper recyclebinMapper;
    @Autowired
    private ConfirmationService confirmationService;
    @Autowired
    private ProductInstallInfoMapper productInstallInfoMapper;
    @Autowired
    private ReceiverMapper receiverMapper;
    @Autowired
    private AfterSalesService afterSalesService;
    @Autowired
    private ServiceOrderMapper serviceOrderMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private AfterSalesMapper afterSalesMapper;
    @Autowired
    private MessageMapper messageMapper;
    /**
     * 新增任务单
     * @param taskOrderDTO
     * @return
     */
    @Override
    @Transactional
    public boolean add(TaskOrderDTO taskOrderDTO) {
        TaskOrder taskOrder = new TaskOrder();
        BeanUtils.copyProperties(taskOrderDTO, taskOrder);
        String taskOrderNumber = taskOrderDTO.getTaskOrderNumber();
        if(taskOrderNumber != null){
            taskOrder.setTaskOrderNumber(taskOrderNumber);
        }
        //根据公司名称获取公司id
        Long customerCompanyId=null;
        if(taskOrderDTO.getCustomerCompanyName() != null){
            customerCompanyId = aUtils.getCustomerCompanyId(taskOrderDTO.getCustomerCompanyName());
            taskOrder.setCustomerCompanyId(customerCompanyId);
        }
        //接收人员id（出服务人员ID？）
        //根据传入的任务接收人姓名列表查询接收人员id，后存入中间表receiver中售后编号和人员id
        if(taskOrderDTO.getReceiverName()!=null){
            for (String s : taskOrderDTO.getReceiverName()) {
                Receiver receiver = new Receiver();
                Long aLong = aUtils.getUserIdByNickName(s);
                receiver.setUserId(aLong);
                receiver.setOrderNumber(taskOrderNumber);
                //保存中间表数据到数据库
                receiverMapper.insert(receiver);
            }
        }
        //客户联系人id手机号
        if(taskOrderDTO.getPhoneNumber() != null&&taskOrderDTO.getContactPersonName()!= null&&customerCompanyId!= null){
            Long contactPersonId = aUtils.getcontactPersonId(taskOrderDTO.getContactPersonName(), taskOrderDTO.getPhoneNumber(), customerCompanyId);
            taskOrder.setContactPersonId(contactPersonId);
        }
        //商务负责热id，技术负责人id，批准人id，核准人id
        if(taskOrderDTO.getBusinessManagerName() != null){
            Long businessManagerId = aUtils.getUserIdByNickName(taskOrderDTO.getBusinessManagerName());
            taskOrder.setBusinessManagerId(businessManagerId);
        }
        if(taskOrderDTO.getTechnicalManagerName() != null){
            Long technicalManagerId = aUtils.getUserIdByNickName(taskOrderDTO.getTechnicalManagerName());
            taskOrder.setTechnicalManagerId(technicalManagerId);
        }
        if(taskOrderDTO.getApproverName() != null){
            Long approverId = aUtils.getUserIdByNickName(taskOrderDTO.getApproverName());
            taskOrder.setApproverId(approverId);
        }
        if(taskOrderDTO.getVerifierName() != null){
            Long verifierId = aUtils.getUserIdByNickName(taskOrderDTO.getVerifierName());
            taskOrder.setVerifierId(verifierId);
        }
        //获取当前登陆用户名
        taskOrder.setCreatedBy(aUtils.getNickNameByuserName(SecurityUtils.getCurrentUsername()));
        taskOrder.setCreateTime(LocalDateTime.now());
        //设置状态

        //插入任务单
        int orderCount = taskorderMapper.insert(taskOrder);
        if (orderCount <= 0) {
            log.error("任务单插入失败");
            throw new RuntimeException("任务单插入失败");
        }
        //产品安装信息中间表
        ProductInstallInfo productInstallInfo = new ProductInstallInfo();
        ProductInstallInfoDTO productInstallInfoDTO = taskOrderDTO.getProductInstallInfo();
        if(productInstallInfoDTO != null){
            BeanUtils.copyProperties(productInstallInfoDTO, productInstallInfo);
            //设置客户公司id
            productInstallInfo.setCustomerCompanyId(customerCompanyId);
            //判断传入的版本和型号是否为空
            if(productInstallInfoDTO.getVersion()!= null && productInstallInfoDTO.getSpecification()!= null){
                Long productId = updateProductInfo(productInstallInfoDTO.getProductName(), productInstallInfoDTO.getVersion(), productInstallInfoDTO.getSpecification());
                if(productId != null){
                    productInstallInfo.setProductId(productId);
                }
                else {
                    Product product = new Product();
                    product.setName(productInstallInfoDTO.getProductName());
                    product.setVersion(productInstallInfoDTO.getVersion());
                    product.setSpecification(productInstallInfoDTO.getSpecification());
                    productMapper.insert(product);
                    productInstallInfo.setProductId(product.getId());
                }
            }
            //否则为空，直接新建一个产品信息不对型号和版本赋值
            else {
                Product product = new Product();
                product.setName(productInstallInfoDTO.getProductName());
                productMapper.insert(product);
                productInstallInfo.setProductId(product.getId());
            }

            //直接新建一个设备安装信息，但是不全需要在后面的服务确认单中补齐，后面的服务确认单会根据服务单号来查询是否存在设备安装信息。
            Long taskOrderId = taskOrder.getId();
            //插入设备安装信息
            int installInfoCount = deviceInstallInfoMapper.insert(productInstallInfo);
            productInstallInfo.setTaskOrderId(taskOrderId);
            if (installInfoCount <= 0) {
                log.error("设备安装信息插入失败");
                throw new RuntimeException("设备安装信息插入失败");
            }
        }
        log.info("任务单 [{}] 新增成功", taskOrder.getTaskOrderNumber());
        aUtils.updateServiceOrderUpdateTime(taskOrder.getTaskOrderNumber());
        return true;

    }

    /**
     * 根据产品名称、版本、规格查询是否存在信息
     * @param productName
     * @param version
     * @param specification
     * @return
     */
    public Long updateProductInfo(
            String productName,
            String version,
            String specification) {

        // Step 1: 检查是否已存在完全匹配的产品（名称 + 版本 + 规格）
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Product::getName, productName)
                .eq(Product::getVersion, version)
                .eq(Product::getSpecification, specification);
        Product existingProduct = productMapper.selectOne(queryWrapper);
        if(existingProduct != null){
            return existingProduct.getId();
        }
        else {
            return null;
        }
    }

    /**
     * 根据ID获取任务单
     * @param id
     * @return
     */
    @Override
    public TaskOrderVO getById(Long id) {
        TaskOrder taskOrder =taskorderMapper.selectByIda(id);
        if ( taskOrder== null) {
            throw new RuntimeException("任务单不存在，ID：" + id);
        }
        // Step 2: 转换为 VO
        TaskOrderVO taskOrderVO = new TaskOrderVO();
        BeanUtils.copyProperties(taskOrder, taskOrderVO);

        //根据售后单号获取接收人名称（中间表查询）
        LambdaQueryWrapper<Receiver> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Receiver::getOrderNumber, taskOrder.getTaskOrderNumber());
        List<Receiver> receivers = receiverMapper.selectList(queryWrapper);
        List<String> receiverName = new ArrayList<>();
        for (Receiver receiver : receivers) {
            //根据用户ID获取名称
            String userNameByUserId = aUtils.getUserNickNameByUserId(receiver.getUserId());
            receiverName.add(userNameByUserId);
        }
        taskOrderVO.setReceiverName(receiverName);

        if(  taskOrder.getCustomerCompanyId() != null)
        taskOrderVO.setCustomerCompanyName(aUtils.getCustomerCompanyNameById(taskOrder.getCustomerCompanyId()));
        if(  taskOrder.getContactPersonId() != null)
        taskOrderVO.setContactPersonName(aUtils.getContactPersonById(taskOrder.getContactPersonId()));
        if(  taskOrder.getContactPersonId() != null)
        taskOrderVO.setPhoneNumber(aUtils.getPhoneNumberById(taskOrder.getContactPersonId()));
        if(  taskOrder.getBusinessManagerId() != null)
        taskOrderVO.setBusinessManagerName(aUtils.getUserNickNameByUserId(taskOrder.getBusinessManagerId()));
        if(  taskOrder.getTechnicalManagerId() != null)
        taskOrderVO.setTechnicalManagerName(aUtils.getUserNickNameByUserId(taskOrder.getTechnicalManagerId()));
        if(  taskOrder.getApproverId() != null)
        taskOrderVO.setApproverName(aUtils.getUserNickNameByUserId(taskOrder.getApproverId()));
        if(  taskOrder.getVerifierId() != null)
        taskOrderVO.setVerifierName(aUtils.getUserNickNameByUserId(taskOrder.getVerifierId()));

        // Step 3: 查询设备安装信息
        LambdaQueryWrapper<ProductInstallInfo> installInfoWrapper = new LambdaQueryWrapper<>();
        installInfoWrapper.eq(ProductInstallInfo::getTaskOrderId, id);
        ProductInstallInfo productInstallInfo = deviceInstallInfoMapper.selectOne(installInfoWrapper);
        ProductInstallInfoVO productInstallInfoVo = new ProductInstallInfoVO();
        if( productInstallInfo != null){
            // Step 4: 转换为 VO
            BeanUtils.copyProperties(productInstallInfo, productInstallInfoVo);
            // Step 5: 如果有 productId，则补充 version 和 specification 和产品名称
            if (productInstallInfo.getProductId() != null) {
                Product product = productMapper.selectById(productInstallInfo.getProductId());
                if (product != null) {
                    productInstallInfoVo.setProductName(product.getName());
                    productInstallInfoVo.setVersion(product.getVersion());
                    productInstallInfoVo.setSpecification(product.getSpecification());
                }
            }
            // Step 6: 拼接到最终结果
            taskOrderVO.setProductInstallInfo(productInstallInfoVo);
        }
        taskOrderVO.setProductInstallInfo(productInstallInfoVo);
        return taskOrderVO;
    }

    /**
     * 根据订单号获取任务单详细
     * @param orderNumber
     * @return
     */
    @Override
    public TaskOrderVO getByOrderNumber(String orderNumber) {
        LambdaQueryWrapper<TaskOrder> taskOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        taskOrderLambdaQueryWrapper.eq(TaskOrder::getTaskOrderNumber, orderNumber);
        taskOrderLambdaQueryWrapper.eq(TaskOrder::getIsDeleted, 1);
        TaskOrder taskOrder = taskorderMapper.selectOne(taskOrderLambdaQueryWrapper);
        if ( taskOrder== null) {
            return null;
        }
        // Step 2: 转换为 VO
        TaskOrderVO taskOrderVO = new TaskOrderVO();
        BeanUtils.copyProperties(taskOrder, taskOrderVO);

        //根据售后单号获取接收人名称（中间表查询）
        LambdaQueryWrapper<Receiver> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Receiver::getOrderNumber, taskOrder.getTaskOrderNumber());
        List<Receiver> receivers = receiverMapper.selectList(queryWrapper);
        List<String> receiverName = new ArrayList<>();
        for (Receiver receiver : receivers) {
            //根据用户ID获取名称
            String userNameByUserId = aUtils.getUserNickNameByUserId(receiver.getUserId());
            receiverName.add(userNameByUserId);
        }
        taskOrderVO.setReceiverName(receiverName);

        if(  taskOrder.getCustomerCompanyId() != null)
            taskOrderVO.setCustomerCompanyName(aUtils.getCustomerCompanyNameById(taskOrder.getCustomerCompanyId()));
        if(  taskOrder.getContactPersonId() != null)
            taskOrderVO.setContactPersonName(aUtils.getContactPersonById(taskOrder.getContactPersonId()));
        if(  taskOrder.getContactPersonId() != null)
            taskOrderVO.setPhoneNumber(aUtils.getPhoneNumberById(taskOrder.getContactPersonId()));
        if(  taskOrder.getBusinessManagerId() != null)
            taskOrderVO.setBusinessManagerName(aUtils.getUserNickNameByUserId(taskOrder.getBusinessManagerId()));
        if(  taskOrder.getTechnicalManagerId() != null)
            taskOrderVO.setTechnicalManagerName(aUtils.getUserNickNameByUserId(taskOrder.getTechnicalManagerId()));
        if(  taskOrder.getApproverId() != null)
            taskOrderVO.setApproverName(aUtils.getUserNickNameByUserId(taskOrder.getApproverId()));
        if(  taskOrder.getVerifierId() != null)
            taskOrderVO.setVerifierName(aUtils.getUserNickNameByUserId(taskOrder.getVerifierId()));

        // Step 3: 查询设备安装信息
        LambdaQueryWrapper<ProductInstallInfo> installInfoWrapper = new LambdaQueryWrapper<>();
        installInfoWrapper.eq(ProductInstallInfo::getTaskOrderId, taskOrder.getId());
        ProductInstallInfo productInstallInfo = deviceInstallInfoMapper.selectOne(installInfoWrapper);
        ProductInstallInfoVO productInstallInfoVo = new ProductInstallInfoVO();
        if( productInstallInfo != null){
            // Step 4: 转换为 VO
            BeanUtils.copyProperties(productInstallInfo, productInstallInfoVo);
            String warrantyDate = productInstallInfo.getWarrantyDate();
            String servicePeriod = productInstallInfo.getServicePeriod();
            // 如果包含时间部分，只取日期部分
            if (warrantyDate != null && warrantyDate.contains(" ")) {
                warrantyDate = warrantyDate.split(" ")[0];
                productInstallInfoVo.setWarrantyDate(warrantyDate);
            }
            if (servicePeriod!=null && servicePeriod.contains(" ")) {
                servicePeriod = servicePeriod.split(" ")[0];
                productInstallInfoVo.setServicePeriod(servicePeriod);
            }

            // Step 5: 如果有 productId，则补充 version 和 specification 和产品名称
            if (productInstallInfo.getProductId() != null) {
                Product product = productMapper.selectById(productInstallInfo.getProductId());
                if (product != null) {
                    productInstallInfoVo.setProductName(product.getName());
                    productInstallInfoVo.setVersion(product.getVersion());
                    productInstallInfoVo.setSpecification(product.getSpecification());
                }
            }
            // Step 6: 拼接到最终结果
            taskOrderVO.setProductInstallInfo(productInstallInfoVo);
        }
        taskOrderVO.setProductInstallInfo(productInstallInfoVo);
        return taskOrderVO;
    }

    /**
     * 修改任务单状态
     * @param id
     * @param status
     * @return
     */
    @Override
    @Transactional
    public ResponseResult updateStatus(Long id, String status) {
        //传入任务单id和状态改变状态（首先任务单和通知单的状态应在最开始保持一致）
        //初始为发布态下推之后状态准备改为进行中,需要通知负责人审核,调用rabbitmq,
        //负责人点击同意后状态改变为进行中,通知调用rabbitmq给任务接收人发送消息,并生成确认单
        //需要判断当前任务单是否存在接收人,如果不存在则返回错误,不允许下推
        //发布-（待审核）-进行-完结（完结态无法推送，需要在总结单中改变，之后变为完结态，所以智能传入进行态）
        //1.根据ID获取任务单
        TaskOrder taskOrder = taskorderMapper.selectById(id);
        if (taskOrder == null) {
            return ResponseResult.error("任务单不存在");
        }

        // 权限检查：只有创建者或特定角色可以修改状态
        String currentUsername = aUtils.getNickNameByuserName(SecurityUtils.getCurrentUsername());
        boolean isCreator = taskOrder.getCreatedBy().equals(currentUsername);
        List<String> currentUserRoles = SecurityUtils.getCurrentUserRoles();
        boolean hasSpecialRole = currentUserRoles.contains(RoleEnum.GENERAL_COMMAND.getCode()) ||
                currentUserRoles.contains(RoleEnum.ADMIN.getCode()) ||
                currentUserRoles.contains(RoleEnum.TECHNICAL_COMMAND.getCode());

        if (!isCreator && !hasSpecialRole) {
            return ResponseResult.error("您没有权限修改该任务单状态");
        }

        if(taskOrder.getStatus().equals(Status.SERVICE_ORDER_STATUS_TO_BE_REVIEWED)){
            return ResponseResult.error("当前任务单状态为待审核，请勿重复操作");
        }
        //获取单号，传入中间表查询是否存在对应的任务接收人
        String orderNumber = taskOrder.getTaskOrderNumber();
        LambdaQueryWrapper<Receiver> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Receiver::getOrderNumber, orderNumber);
        List<Receiver> receivers = receiverMapper.selectList(queryWrapper);
        if (receivers.size() == 0) {
            return ResponseResult.error("任务单不存在对应的接收人,请先添加任务接收人");
        }
        // 先收集所有接收人员姓名
        List<String> allReceiverNames = new ArrayList<>();
        for (Receiver r : receivers) {
            allReceiverNames.add(aUtils.getUserNickNameByUserId(r.getUserId()));
        }
        String allReceiversStr = String.join(",", allReceiverNames);

        for (Receiver receiver : receivers) {
            //根据对应的用户获取到userid，根据userid查询联系人信息，获取到用户的角色然后去通知对应的负责人角色
            //一个任务接收人可能存在多种角色
            Long userId = receiver.getUserId();
            //根据用户id获取角色列表
            List<String> roleByUserId = aUtils.getRoleByUserId(userId);
            for (String s : roleByUserId) {
                String title = "任务单"+orderNumber+"审核通知";
                String content = "请审核：" + aUtils.getUserNickNameByUserId(userId) +
                        "（本次全部出行人：" + allReceiversStr + "）" +"\n"+
                        " 本次服务客户：" + aUtils.getCustomerCompanyNameById(taskOrder.getCustomerCompanyId()) +"\n"+
                        " 售后单号：" + taskOrder.getTaskOrderNumber();
                Map<String, Object> message = new HashMap<>();
                message.put("orderNumber", orderNumber);
                message.put("title", title);
                message.put("content", content);
                message.put("createTime", LocalDateTime.now());
                message.put("businessType", Status.TASK_ORDER);
                message.put("orderId", id);
                String routingKey = RabbitMQConstants.ROUTING_KEY_TASK_ORDER;
                //根据角色判断需要通知哪些人
                //生产
                if (s.equals(RoleEnum.PRODUCTION_TECHNOLOGY.getCode())) {
                    message.put("roleName",RoleEnum.PRODUCTION_LEADER.getCode());
                }
                //综合
                else if (s.equals(RoleEnum.GENERAL_DEPARTMENT.getCode())) {
                    message.put("roleName",RoleEnum.GENERAL_LEADER.getCode());
                }
                //测控
                else if (s.equals(RoleEnum.MC_DEPARTMENT.getCode())) {
                    message.put("roleName",RoleEnum.MC_LEADER.getCode());
                }
                //销售
                else if (s.equals(RoleEnum.SALES_DEPARTMENT.getCode())) {
                    message.put("roleName",RoleEnum.SALES_LEADER.getCode());
                }
                //仪表
                else if (s.equals(RoleEnum.INSTRUMENT_DEPARTMENT.getCode())) {
                    message.put("roleName",RoleEnum.INSTRUMENT_LEADER.getCode());
                }
                if (message.get("roleName")!=null) {
                    TaskReviewMessageDTO taskReviewMessageDTO = new TaskReviewMessageDTO();
                    taskReviewMessageDTO.setOrderNumber(orderNumber);
                    taskReviewMessageDTO.setTitle(title);
                    taskReviewMessageDTO.setContent(content);
                    taskReviewMessageDTO.setBusinessType(Status.TASK_ORDER);
                    taskReviewMessageDTO.setOrderId(id);
                    taskReviewMessageDTO.setRoleName((String)message.get("roleName"));
                    taskReviewMessageDTO.setSenderName(SecurityUtils.getCurrentUsername());
                    taskReviewMessageDTO.setRelatedId(userId);
                    taskReviewMessageDTO.setSenderName(SecurityUtils.getCurrentUsername());
                    taskReviewMessageDTO.setMessageType(MessageTypeEnum.BUSINESS_REVIEW.getCode());
                    // 发送消息到交换机，通过 routingKey 投递到对应队列
                    // 消息接收方通过绑定的ordernumber和businessType判断这是来自于任务接收单的消息，对消息进行处理同意则改变状态为进行中，不同意则改变状态为发布态
                    rabbitTemplate.convertAndSend(
                            RabbitMQConstants.EXCHANGE,
                            routingKey,
                            taskReviewMessageDTO
                    );
                    System.out.println("消息已发送至: " + message.get("roleName") + ", routingKey: " + routingKey);
                }
            }
        }
        //改变状态为待审核
        status=Status.SERVICE_ORDER_STATUS_TO_BE_REVIEWED;
        //修改总括表同步为待审核
        LambdaQueryWrapper<AfterSales> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(AfterSales::getOrderNumber,orderNumber);
        //修改总括表同步为待审核
        AfterSales afterSales = afterSalesMapper.selectOne(wrapper1);
        afterSales.setStatus(Status.SERVICE_ORDER_STATUS_TO_BE_REVIEWED);
        afterSalesMapper.updateById(afterSales);
        if(taskorderMapper.updateStatus(id, status)){
            return ResponseResult.success("任务单审核成功");
        }
        return ResponseResult.error("任务单审核失败");
    }


    /**
     * 生成Excel到指定位置
     * @param id
     */
    @Override
    public void generateExcel(Long id) throws Exception {
        // 定义模板位置
        String templatePath = "E:\\plm\\modelfeil\\任务单模板.xlsx";
        // 获取数据
        TaskOrderVO taskOrderVO = getById(id);
        //获取确认单详情这个阶段应该只填入了服务单号和外键任务单id，其他信息都为空
        //ConfirmationOrderVO confirmationOrderVO = confirmationService.getByTaskOrderId(id);

        try (FileInputStream fis = new FileInputStream(templatePath);
             Workbook workbook = new XSSFWorkbook(fis)) {

            Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
            Sheet sheet2 = workbook.getSheetAt(1);
            setCellValue(sheet2, 3, 6, taskOrderVO.getTaskOrderNumber());

            // 创建水平+垂直居中样式
            CellStyle centerStyle = workbook.createCellStyle();
            centerStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
            centerStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
            centerStyle.setWrapText(true); // 自动换行
            centerStyle.setBorderTop(BorderStyle.THIN);    // 上边框
            centerStyle.setBorderBottom(BorderStyle.THIN); // 下边框
            centerStyle.setBorderLeft(BorderStyle.THIN);   // 左边框
            centerStyle.setBorderRight(BorderStyle.THIN);  // 右边框
            //填充sheet1表格的字段
            // 填充基础字段
            fillBasicFields(sheet, taskOrderVO,centerStyle);
            // 填充产品安装信息
            if(taskOrderVO.getProductInstallInfo() != null)
            fillProductInstallInfo(sheet, taskOrderVO.getProductInstallInfo(), centerStyle);
            // 填充其他字段
            fillOtherFields(sheet, taskOrderVO);

            //填充sheet2表格的字段

            // 设置输出路径
            String outputFileName = taskOrderVO.getTaskOrderNumber() + "-" + taskOrderVO.getCustomerCompanyName() +"任务单"+ ".xlsx";
            String outputPath = "E:\\plm\\modelfeil\\" + outputFileName;
            // 写入文件
            try (FileOutputStream fos = new FileOutputStream(outputPath)) {
                workbook.write(fos);
            }
        } catch (Exception e) {
            throw new RuntimeException("生成Excel失败", e);
        }

    }

    /**
     * 下载Excel
     * @param id
     * @param response
     */
    @Override
    public void generateExcel(Long id, HttpServletResponse response) {
        // 定义模板位置
        String templatePath = "D:\\Code\\crm\\mode\\任务单模板.xlsx";
       // String templatePath = "E:\\plm\\modelfeil\\任务单模板.xlsx";
        // 获取数据

        TaskOrderVO taskOrderVO = getById(id);

        try (FileInputStream fis = new FileInputStream(templatePath);
             Workbook workbook = new XSSFWorkbook(fis)) {

            Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
            Sheet sheet2 = workbook.getSheetAt(1); // 获取第二个工作表确认单

            // 创建水平+垂直居中样式（用于 B12）
            CellStyle centerStyle = workbook.createCellStyle();
            centerStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
            centerStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
            centerStyle.setWrapText(true); // 自动换行
            centerStyle.setBorderTop(BorderStyle.THIN);    // 上边框
            centerStyle.setBorderBottom(BorderStyle.THIN); // 下边框
            centerStyle.setBorderLeft(BorderStyle.THIN);   // 左边框
            centerStyle.setBorderRight(BorderStyle.THIN);  // 右边框

            // 填充基础字段
            fillBasicFields(sheet, taskOrderVO, centerStyle);
            fillBasicFields2(sheet2, taskOrderVO, centerStyle);
            // 填充产品安装信息
            fillProductInstallInfo(sheet, taskOrderVO.getProductInstallInfo(), centerStyle);
            // 填充其他字段
            fillOtherFields(sheet, taskOrderVO);

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            String fileName = taskOrderVO.getTaskOrderNumber() + "-" + taskOrderVO.getCustomerCompanyName() + "任务单" + ".xlsx";
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName);

            // 将 Excel 写入响应输出流
            workbook.write(response.getOutputStream());

        } catch (Exception e) {
            throw new RuntimeException("生成Excel失败", e);
        }
    }

    /**
     * 修改任务单
     * @param taskOrderDTO
     * @return
     */
    @Override
    @Transactional
    public ResponseResult update(TaskOrderDTO taskOrderDTO) {
        // 将 DTO 转换为 TaskOrder 实体
        TaskOrder taskOrder= taskorderMapper.selectById(taskOrderDTO.getId());
        if(taskOrder == null){
            throw new RuntimeException("任务单不存在");
        }
        if(!taskOrder.getStatus().equals(Status.SERVICE_ORDER_STATUS_EDITING)
                && !taskOrder.getStatus().equals(Status.SERVICE_ORDER_STATUS_CONFIRMED)
                && !taskOrder.getStatus().equals(Status.SERVICE_ORDER_STATUS_PUBLISHED)
                && !taskOrder.getStatus().equals(Status.SERVICE_ORDER_STATUS_PROCESSING)){
            return ResponseResult.error("当前状态"+taskOrder.getStatus()+"不能修改");
        }
        // 权限检查：只有创建者或特定角色可以修改
        String currentUsername = aUtils.getNickNameByuserName(SecurityUtils.getCurrentUsername());
        boolean isCreator = taskOrder.getCreatedBy().equals(currentUsername);
        List<String> currentUserRoles = SecurityUtils.getCurrentUserRoles();
        boolean hasSpecialRole = currentUserRoles.contains(RoleEnum.GENERAL_COMMAND.getCode()) ||
                currentUserRoles.contains(RoleEnum.ADMIN.getCode()) ||
                currentUserRoles.contains(RoleEnum.TECHNICAL_COMMAND.getCode());

        if (!isCreator && !hasSpecialRole) {
            return ResponseResult.error("当前用户没有修改权限，请联系管理员处理");
        }

        //判断当前状态是否都不满足确认发布编辑状态+进行中状态（进行中可以修改，需要判断角色是否满足要求）
        //销售经理需要去通知单中查询该单的销售经理，以及任务接收人是否存在（如存在则添加接收人的领导可修改）
        //根据售后编号查询通知单
        LambdaQueryWrapper<ServiceOrder> serviceOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        serviceOrderLambdaQueryWrapper.eq(ServiceOrder::getServiceOrderNumber, taskOrder.getTaskOrderNumber());
        BeanUtils.copyProperties(taskOrderDTO, taskOrder);

        // 设置客户公司 ID
        Long customerCompanyId=null;
        if(taskOrderDTO.getCustomerCompanyName() != null){
            customerCompanyId = aUtils.getCustomerCompanyId(taskOrderDTO.getCustomerCompanyName());
            taskOrder.setCustomerCompanyId(customerCompanyId);
        }

        //任务接收人ID
        //根据接收人姓名获取id，先根据编号删除接收中间表，然后查询id再重新添加Receiver
        if(taskOrderDTO.getReceiverName()!=null) {
            LambdaQueryWrapper<Receiver> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Receiver::getOrderNumber, taskOrder.getTaskOrderNumber());
            receiverMapper.delete(wrapper);
            for (String s : taskOrderDTO.getReceiverName()) {
                Receiver receiver = new Receiver();
                receiver.setOrderNumber(taskOrder.getTaskOrderNumber());
                receiver.setUserId(aUtils.getUserIdByNickName(s));
                receiverMapper.insert(receiver);
            }
        }

        if(taskOrderDTO.getContactPersonName() != null&&taskOrderDTO.getPhoneNumber() != null){
            // 设置联系人 ID 和手机号
            taskOrder.setContactPersonId(aUtils.getcontactPersonId(
                    taskOrderDTO.getContactPersonName(),
                    taskOrderDTO.getPhoneNumber(),
                    customerCompanyId
            ));
        }

        // 设置商务负责人、技术负责人等
        if(taskOrderDTO.getBusinessManagerName() != null)
        taskOrder.setBusinessManagerId(aUtils.getUserIdByNickName(taskOrderDTO.getBusinessManagerName()));
        if(taskOrderDTO.getTechnicalManagerName() != null)
        taskOrder.setTechnicalManagerId(aUtils.getUserIdByNickName(taskOrderDTO.getTechnicalManagerName()));
        if(taskOrderDTO.getApproverName() != null)
        taskOrder.setApproverId(aUtils.getUserIdByNickName(taskOrderDTO.getApproverName()));
        if(taskOrderDTO.getVerifierName() != null)
        taskOrder.setVerifierId(aUtils.getUserIdByNickName(taskOrderDTO.getVerifierName()));

        // 获取当前登录用户名
        //taskOrder.setCreatedBy(SecurityUtils.getCurrentUsername());

        if(taskOrderDTO.getProductInstallInfo() != null &&
                taskOrderDTO.getProductInstallInfo().getProductName() != null &&
                !taskOrderDTO.getProductInstallInfo().getProductName().isEmpty()) {
            // 1. 先根据任务单号查询并删除旧的产品安装信息
            Long TaskOrderId = taskOrder.getId();
            LambdaQueryWrapper<ProductInstallInfo> oldInstallInfoQuery = new LambdaQueryWrapper<>();
            oldInstallInfoQuery.eq(ProductInstallInfo::getTaskOrderId, TaskOrderId);
            if(deviceInstallInfoMapper.selectOne(oldInstallInfoQuery)!=null) {
                int deleteCount = deviceInstallInfoMapper.delete(oldInstallInfoQuery);
                if (deleteCount == 0) {
                    log.error("删除旧的设备安装信息失败");
                    throw new RuntimeException("删除旧的设备安装信息失败");
                }
                else
                {
                    // 2. 新建产品安装信息
                    ProductInstallInfo productInstallInfo = new ProductInstallInfo();
                    ProductInstallInfoDTO productInstallInfoDTO = taskOrderDTO.getProductInstallInfo();
                    BeanUtils.copyProperties(productInstallInfoDTO, productInstallInfo);
                    //设置客户公司id
                    productInstallInfo.setCustomerCompanyId(customerCompanyId);
                    //判断传入的版本和型号是否为空
                    if(productInstallInfoDTO.getProductName()==null){
                        throw new RuntimeException("请输入产品名称");
                    }
                    if(productInstallInfoDTO.getVersion()==null){
                        productInstallInfoDTO.setVersion("未知");
                    }
                    if(productInstallInfoDTO.getSpecification()==null){
                        productInstallInfoDTO.setSpecification("未知");
                    }
                    Long productId = updateProductInfo(productInstallInfoDTO.getProductName(),productInstallInfoDTO.getVersion(), productInstallInfoDTO.getSpecification());
                    if(productId != null){
                        productInstallInfo.setProductId(productId);
                    }
                    else {
                        Product product = new Product();
                        product.setName(productInstallInfoDTO.getProductName());
                        product.setVersion(productInstallInfoDTO.getVersion());
                        product.setSpecification(productInstallInfoDTO.getSpecification());
                        productMapper.insert(product);
                        productInstallInfo.setProductId(product.getId());
                    }

                    //服务单单号
                    productInstallInfo.setTaskOrderId(taskOrder.getId());
                    //直接新建一个设备安装信息，但是不全需要在后面的服务确认单中补齐，后面的服务确认单会根据服务单号来查询是否存在设备安装信息。
                    //插入设备安装信息
                    int installInfoCount = deviceInstallInfoMapper.insert(productInstallInfo);
                    if (installInfoCount <= 0) {
                        log.error("设备安装信息插入失败");
                        throw new RuntimeException("设备安装信息插入失败");
                    }
                }
            }
            else
            {
                // 2. 新建产品安装信息
                ProductInstallInfo productInstallInfo = new ProductInstallInfo();
                ProductInstallInfoDTO productInstallInfoDTO = taskOrderDTO.getProductInstallInfo();
                BeanUtils.copyProperties(productInstallInfoDTO, productInstallInfo);
                //设置客户公司id
                productInstallInfo.setCustomerCompanyId(customerCompanyId);
                //判断传入的版本和型号是否为空
                if(productInstallInfoDTO.getProductName()==null){
                    throw new RuntimeException("请输入产品名称");
                }
                if(productInstallInfoDTO.getVersion()==null){
                    productInstallInfoDTO.setVersion("未知");
                }
                if(productInstallInfoDTO.getSpecification()==null){
                    productInstallInfoDTO.setSpecification("未知");
                }
                Long productId = updateProductInfo(productInstallInfoDTO.getProductName(),productInstallInfoDTO.getVersion(), productInstallInfoDTO.getSpecification());
                if(productId != null){
                    productInstallInfo.setProductId(productId);
                }
                else {
                    Product product = new Product();
                    product.setName(productInstallInfoDTO.getProductName());
                    product.setVersion(productInstallInfoDTO.getVersion());
                    product.setSpecification(productInstallInfoDTO.getSpecification());
                    productMapper.insert(product);
                    productInstallInfo.setProductId(product.getId());
                }

                //服务单单号
                productInstallInfo.setTaskOrderId(taskOrder.getId());
                //直接新建一个设备安装信息，但是不全需要在后面的服务确认单中补齐，后面的服务确认单会根据服务单号来查询是否存在设备安装信息。
                //插入设备安装信息
                int installInfoCount = deviceInstallInfoMapper.insert(productInstallInfo);
                if (installInfoCount <= 0) {
                    log.error("设备安装信息插入失败");
                    throw new RuntimeException("设备安装信息插入失败");
                }
            }

        }


        // 4. 更新任务单主表
        int orderCount = taskorderMapper.updateById(taskOrder);
        if (orderCount <= 0) {
            log.error("任务单更新失败");
            throw new RuntimeException("任务单更新失败");
        }

        log.info("任务单 [{}] 更新成功", taskOrder.getTaskOrderNumber());
        aUtils.updateServiceOrderUpdateTime(taskOrder.getTaskOrderNumber());
        return ResponseResult.success("任务单更新成功");
    }

    /**
     * 分页条件查询
     * @param pageNum
     * @param pageSize
     * @param customerName
     * @param technicalManagerName
     * @param businessManagerName
     * @param taskOrderNumber
     * @param startDate
     * @param endDate
     * @param status
     * @return
     */
    @Override
    public IPage<TaskOrderVO> getByPage(int pageNum, int pageSize,
                                        String customerName, String technicalManagerName,
                                        String receiverName,
                                        String businessManagerName, String taskOrderNumber,
                                        String startDate, String endDate, String status) {
        Page<TaskOrderVO> page = new Page<>(pageNum, pageSize);
        String currentUsername = SecurityUtils.getCurrentUsername();
        IPage<TaskOrderVO> taskOrdersByPage = taskorderMapper.getTaskOrdersByPage(page, customerName, technicalManagerName, receiverName,
                businessManagerName, taskOrderNumber,
                startDate, endDate, status, currentUsername);
        // 遍历每条记录，把 receiverName 从 String 转成 List<String>
        for (TaskOrderVO vo : taskOrdersByPage.getRecords()) {
            if (vo.getReceiverNameStr() != null && !vo.getReceiverNameStr().isEmpty()) {
                String[] names = vo.getReceiverNameStr().split(",");
                vo.setReceiverName(Arrays.asList(names));
            }
        }
        return taskOrdersByPage;
    }


    /**
     * 批量删除
     * @param ids
     * @return
     */
    @Override
    public boolean batchDelete(List<Long> ids) {
        // 获取当前用户信息
        String currentUsername = aUtils.getNickNameByuserName(SecurityUtils.getCurrentUsername());
        List<String> currentUserRoles = SecurityUtils.getCurrentUserRoles();
        boolean hasSpecialRole = currentUserRoles.contains(RoleEnum.GENERAL_COMMAND.getCode()) ||
                currentUserRoles.contains(RoleEnum.ADMIN.getCode()) ||
                currentUserRoles.contains(RoleEnum.TECHNICAL_COMMAND.getCode());

        //创建一个回收站记录
        RecycleBinOrder recycleBinOrder = new RecycleBinOrder();
        for (Long id : ids) {
            TaskOrder taskOrder = taskorderMapper.selectById(id);
            if(taskOrder == null){
                throw new RuntimeException("未找到该任务单"+id);
            }

            // 权限检查：只有创建者或特定角色可以删除
            boolean isCreator = taskOrder.getCreatedBy().equals(currentUsername);
            if (!isCreator && !hasSpecialRole) {
                throw new RuntimeException("您没有权限删除任务单：" + taskOrder.getTaskOrderNumber());
            }

            //判断是否存在下级订单存在则不允许删除
            if(taskorderMapper.getByOrderNumberToDown(taskOrder.getTaskOrderNumber())){
                log.error("该任务单存在下级订单，不允许删除");
                return false;
            }
            //设置前置订单状态为已确认
            serviceOrderMapper.updateStatusByOrderNumber(taskOrder.getTaskOrderNumber(), Status.SERVICE_ORDER_STATUS_CONFIRMED);
            //设置总括表也为退回已确认
            afterSalesMapper.updateStatusByOrderNumber(taskOrder.getTaskOrderNumber(), Status.SERVICE_ORDER_STATUS_CONFIRMED);
            //删除product_install_info
            LambdaQueryWrapper<ProductInstallInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ProductInstallInfo::getTaskOrderId, taskOrder.getId());
            productInstallInfoMapper.delete(wrapper);
            recycleBinOrder.setDeletedBy(SecurityUtils.getCurrentUsername());
            recycleBinOrder.setOrderType(Status.TASK_ORDER);
            recycleBinOrder.setOrderId(id);
            recycleBinOrder.setDeleteTime(LocalDateTime.now());
            recycleBinOrder.setCustomerName(aUtils.getCustomerCompanyNameById(taskOrder.getCustomerCompanyId()));
            recyclebinMapper.insert(recycleBinOrder);
            //改变状态为0
            taskorderMapper.setisdeleted(id);
            //删除任务接收人中间表
            receiverMapper.delete(new QueryWrapper<Receiver>().eq("order_number", taskOrder.getTaskOrderNumber()));
            //删除对应的发出去的消息
            LambdaQueryWrapper<Message> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Message::getOrderNumber, taskOrder.getTaskOrderNumber())
                    .eq(Message::getBusinessType, Status.TASK_ORDER);
            messageMapper.delete(wrapper1);
        }
        return true;
    }


    @Autowired
    private MinioService minioService;
    /**
     * 上传图片更新数据库并归档
     * @param image
     * @return
     */
    @Override
    public TaskOrderVO updateByImage(MultipartFile image) throws Exception {
        //图片转换
        String s1 =aUtils.getFileContentAsBase64(image, true);
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "image="+s1);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/rest/2.0/ocr/v1/table?access_token=" + getAccessToken())
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        String s = response.body().string();
        System.out.println(s);
        JSONObject jsonObject = new JSONObject(s);
        // 从 tables_result 中获取 body 数组
        JSONArray tablesResult = jsonObject.getJSONArray("tables_result");
        JSONObject firstTable = tablesResult.getJSONObject(0);
        JSONArray body1 = firstTable.getJSONArray("body");
        JSONArray header1 = firstTable.getJSONArray("header");
        TaskOrderVO taskOrderVO = new TaskOrderVO();
        String receiverName = extractFieldValue(body1, "接收人员：");
        String taskOrderNumber = extractFieldValue(body1, "编号：");
        String customerCompanyName = extractFieldValue(body1, "用户名称");
        String contactPersonName = extractFieldValue(body1, "联系人");
        String phoneNumber = extractFieldValue(body1, "电话");
        String businessManagerName = extractFieldValue(body1, "商务负责人");
        String technicalManagerName = extractFieldValue(body1, "技术负责人");
        String productName = extractFieldValue(body1, "产品名称");
        String installationLocation = extractFieldValue(body1, "安装地点");
        String version = extractFieldValue(body1, "型号");
        String measurementMedium = extractFieldValue(body1, "测量介质");
        String specification = extractFieldValue(body1, "仪表通径");
        String instrumentNumber = extractFieldValue(body1, "仪表编号");
        String warrantyDate = extractFieldValue(body1, "产品购买\n日期");
        String communicationMethod = extractFieldValue(body1, "通讯方式");
        String safetyLevel = extractFieldValue(body1, "安全等级");
        String safetyNotes = extractFieldValue(body1, "安全注意事项");
        String pastExperience = extractFieldValue(body1, "往年\n现场经验");
        String supportContent = extractFieldValue(body1, "技术支持\n内容");
        String supportPlan = extractFieldValue(body1, "技术支持\n方案");
        String requiredDays = extractFieldValue(body1, "要求完成\n时间");
        String actualDays = extractFieldValue(body1, "实际完成\n天数");
        String approverName = extractFieldValue(body1, "任务批准人");
        String verifierName = extractFieldValue(body1, "任务核准人");
        String createdBy = extractFieldValue(body1, "制表人员及日期");
        //接收任务接收人员姓名之后处理方法（、隔开识别、）存入list
        List<String> receiverNames = Arrays.asList(receiverName.split("、"));
        taskOrderVO.setReceiverName(receiverNames);
        //taskOrderVO.setReceiverName(receiverName);
        taskOrderVO.setTaskOrderNumber(taskOrderNumber);
        taskOrderVO.setCustomerCompanyName(customerCompanyName);
        taskOrderVO.setContactPersonName(contactPersonName);
        taskOrderVO.setPhoneNumber(phoneNumber);
        taskOrderVO.setBusinessManagerName(businessManagerName);
        taskOrderVO.setTechnicalManagerName(technicalManagerName);
        ProductInstallInfoVO productInstallInfoVO = new ProductInstallInfoVO();
        productInstallInfoVO.builder()
                .productName(productName)
                .version(version)
                .specification(specification)
                .installationLocation(installationLocation)
                .instrumentNumber(instrumentNumber)
                .productPurchaseDate(warrantyDate)
                .measurementMedium(measurementMedium)
                .safetyLevel(safetyLevel)
                .safetyNotes(safetyNotes)
                .communicationMethod(communicationMethod)
                        .build();
        taskOrderVO.setProductInstallInfo(productInstallInfoVO);
        taskOrderVO.setPastExperience(pastExperience);
        taskOrderVO.setSupportContent(supportContent);
        taskOrderVO.setSupportPlan(supportPlan);
        taskOrderVO.setRequiredDays(requiredDays);
        taskOrderVO.setActualDays(actualDays);
        taskOrderVO.setApproverName(approverName);
        taskOrderVO.setVerifierName(verifierName);
        taskOrderVO.setCreatedBy(createdBy);

        //创建上传图片到minio获取图片的objectName
        String objectName = minioService.uploadFile(image);
        //根据图片objectName获取预签名url存入实体类中
        String presignedUrl = minioService.getPresignedUrl(objectName);
        taskOrderVO.setImagesUrl(presignedUrl);

        //返回vo给前端展示
        return taskOrderVO;

    }



    /**
     * 从 OCR 的 body 数组中提取指定字段名后面的值
     * @param jsonArray JSONArray 类型的 OCR 表格 body 数据
     * @param fieldName 要查找的字段名，如 "服务单号"、"工作明细" 等
     * @return 对应字段值，未找到或出错返回 null
     */
    public String extractFieldValue(JSONArray jsonArray, String fieldName) {
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject currentCell = jsonArray.getJSONObject(i);
            String word = currentCell.optString("words", "").trim();

            if (fieldName.equals(word)) {
                if (i + 1 < jsonArray.length()) {
                    JSONObject nextCell = jsonArray.getJSONObject(i + 1);
                    return nextCell.optString("words", "").trim();
                }
            }
        }
        return null;
    }


    //  将任务单对象转换为 VO 层对象
//    private TaskOrderVO convertToVO(TaskOrder taskOrder) {
//        TaskOrderVO vo = new TaskOrderVO();
//        BeanUtils.copyProperties(taskOrder, vo);
//        if(taskOrder.getReceiverId() != null)
//         vo.setReceiverName(aUtils.getUserNameByUserId(taskOrder.getReceiverId()));
//        if(taskOrder.getCustomerCompanyId() != null)
//         vo.setCustomerCompanyName(aUtils.getCustomerCompanyNameById(taskOrder.getCustomerCompanyId()));
//        if(taskOrder.getContactPersonId() != null)
//         vo.setContactPersonName(aUtils.getContactPersonById(taskOrder.getContactPersonId()));
//        if(taskOrder.getContactPersonId() != null)
//         vo.setPhoneNumber(aUtils.getPhoneNumberById(taskOrder.getContactPersonId()));
//        if(taskOrder.getTechnicalManagerId() != null)
//         vo.setTechnicalManagerName(aUtils.getUserNameByUserId(taskOrder.getTechnicalManagerId()));
//        if(taskOrder.getBusinessManagerId() != null)
//         vo.setBusinessManagerName(aUtils.getUserNameByUserId(taskOrder.getBusinessManagerId()));
//         //获取设备安装信息
//        LambdaQueryWrapper<ProductInstallInfo> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(ProductInstallInfo::getTaskOrderId, taskOrder.getId());
//        ProductInstallInfo productInstallInfo=productInstallInfoMapper.selectOne(queryWrapper);
//        if (productInstallInfo != null) {
//            ProductInstallInfoVO productInstallInfoVO = new ProductInstallInfoVO();
//            BeanUtils.copyProperties(productInstallInfo, productInstallInfoVO);
//            vo.setProductInstallInfo(productInstallInfoVO);
//        }
//        return vo;
//    }
    private void fillBasicFields(Sheet sheet, TaskOrderVO vo, CellStyle centerStyle) {
        // 接收人员（B3）
        setCellValue(sheet, 3, 2, String.join(",", vo.getReceiverName()));
        // 编号（F3）
        setCellValue(sheet, 3, 6, vo.getTaskOrderNumber());
        // 用户名称（C4）
        setCellValue(sheet, 4, 3, vo.getCustomerCompanyName());
        // 联系人（C5）、电话（F5）
        setCellValue(sheet, 5, 3, vo.getContactPersonName());
        setCellValue(sheet, 5, 6, vo.getPhoneNumber());
        // 商务负责人（C6）、技术负责人（F6）
        setCellValue(sheet, 6, 3, vo.getBusinessManagerName());
        setCellValue(sheet, 6, 6, vo.getTechnicalManagerName());
        // 往年经验（B11）
        setCellValue(sheet, 11, 2, vo.getPastExperience());
        // 技术支持内容（B12）
        setCellValue(sheet, 12, 2, vo.getSupportContent(), centerStyle);
        // 技术支持方案（F12）
        setCellValue(sheet, 12, 6, vo.getSupportPlan(), centerStyle);
        // 要求完成天数（B17）、实际完成天数（F17）
        setCellValue(sheet, 17, 2, vo.getRequiredDays());
        setCellValue(sheet, 17, 6, vo.getActualDays());
        // 任务批准人（B18）、任务核准人（F18）
        setCellValue(sheet, 18, 2, vo.getApproverName());
        setCellValue(sheet, 18, 6, vo.getVerifierName());
        // 制表人及时间（F19）
        LocalDateTime now = LocalDateTime.now();
        String formattedTime ="制表人员及日期： "+ vo.getCreatedBy() + " "+ now.getYear() + "." + now.getMonthValue() + "." + now.getDayOfMonth();
        setCellValue(sheet, 19, 5, formattedTime);
    }
    private void fillBasicFields2(Sheet sheet, TaskOrderVO vo, CellStyle centerStyle) {
        // 编号（F3）
        setCellValue(sheet, 3, 6, vo.getTaskOrderNumber());
        // 用户名称（C4）
        setCellValue(sheet, 4, 3, vo.getCustomerCompanyName());
        // 联系人（C5）、电话（F5）
        setCellValue(sheet, 5, 3, vo.getContactPersonName());
        setCellValue(sheet, 5, 5, vo.getPhoneNumber());
    }
    private void fillProductInstallInfo(Sheet sheet, ProductInstallInfoVO productInfo ,CellStyle centerStyle) {
        // 产品名称（C7）、安装地点（F7）
        setCellValue(sheet, 7, 3, productInfo.getProductName());
        setCellValue(sheet, 7, 7, productInfo.getInstallationLocation(),centerStyle);
        // 型号（C8）、测量介质（F8）
        setCellValue(sheet, 8, 3, productInfo.getVersion());
        setCellValue(sheet, 8, 7, productInfo.getMeasurementMedium());
        // 仪表通径（C9）、仪表编号（E9）、产品购买日期（F9）
        setCellValue(sheet, 9, 3, productInfo.getSpecification());
        setCellValue(sheet, 9, 5, productInfo.getInstrumentNumber());
        setCellValue(sheet, 9, 7, productInfo.getProductPurchaseDate());
        // 通讯方式（C10）、安全等级（E10）、安全注意事项（F10）
        setCellValue(sheet, 10, 3, productInfo.getCommunicationMethod());
        setCellValue(sheet, 10, 5, productInfo.getSafetyLevel());
        setCellValue(sheet, 10, 7, productInfo.getSafetyNotes());
    }
    private void fillOtherFields(Sheet sheet, TaskOrderVO vo) {
        // 其他需要填充的字段...
    }
    private void setCellValue(Sheet sheet, int rowIndex, int columnIndex, Object value) {
        Row row = sheet.getRow(rowIndex - 1); // 行号从0开始
        if (row == null) {
            row = sheet.createRow(rowIndex - 1);
        }
        Cell cell = row.getCell(columnIndex - 1); // 列号从0开始
        if (cell == null) {
            cell = row.createCell(columnIndex - 1);
        }

        if (value instanceof LocalDateTime) {
            cell.setCellValue(((LocalDateTime) value).toString());
        } else if (value instanceof Integer) {
            cell.setCellValue((Integer) value);
        } else if (value != null) {
            cell.setCellValue(value.toString());
        } else {
            cell.setCellValue("");
        }
    }
    private void setCellValue(Sheet sheet, int rowIndex, int columnIndex, Object value, CellStyle style) {
        Row row = sheet.getRow(rowIndex - 1);
        if (row == null) {
            row = sheet.createRow(rowIndex - 1);
        }
        Cell cell = row.getCell(columnIndex - 1);
        if (cell == null) {
            cell = row.createCell(columnIndex - 1);
        }

        String stringValue = value == null ? "" : value.toString();
        if (value instanceof LocalDateTime) {
            cell.setCellValue(((LocalDateTime) value).toString());
        } else if (value instanceof Integer) {
            cell.setCellValue((Integer) value);
        } else {
            cell.setCellValue(stringValue);
        }

        if (style != null) {
            cell.setCellStyle(style);
        }
    }

    /**
     * 工厂模式 恢复工单状态
     * @param orderId
     * @return
     */
    @Override
    public boolean restoreOrderById(Long orderId) {
        //设置任务单删除状态为1
        TaskOrder taskOrder = new TaskOrder();
        taskOrder.setIsDeleted(1);
        return taskorderMapper.update(taskOrder, new LambdaQueryWrapper<TaskOrder>().eq(TaskOrder::getId, orderId)) > 0;

    }

    /**
     * 彻底删除工单
     * @param orderId
     * @return
     */
    @Override
    public boolean deleteOrderById(Long orderId) {
        return taskorderMapper.deleteById(orderId) > 0;
    }
}
